﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Text;
using FileHelpers;

namespace CleanInvoiceCSV
{
    class Program
    {
        static void Main(string[] args)
        {
            string filename = ConfigurationManager.AppSettings["csvPath"];
            string localFolderPath = ConfigurationManager.AppSettings["pdfPath"];

            if(!localFolderPath.EndsWith(@"\"))
            {
                localFolderPath += @"\";
            }

            FileHelperEngine engine = new FileHelperEngine(typeof(InvoiceRecord));

            InvoiceRecord[] records = engine.ReadFile(filename) as InvoiceRecord[];

            List<InvoiceRecord> missingPDFs = new List<InvoiceRecord>();

            using (CsvFileWriter writer = new CsvFileWriter(localFolderPath + "metadata.csv"))
            {
                CsvRow header = new CsvRow();
                header.AddRange(InvoiceRecord.CsvHeaders());
                writer.WriteRow(header);
                foreach (InvoiceRecord record in records)
                {
                    string pdfDocumentName = record.DocumentNumber;
                    string documentPath = string.Format("{0}{1}.pdf", localFolderPath, pdfDocumentName);
                    if(File.Exists(documentPath))
                    {
                        CsvRow current = new CsvRow();
                        current.AddRange(record.ToCsvList());
                        writer.WriteRow(current);
                    }else
                    {
                        missingPDFs.Add(record);
                    }
                }
            }
            Console.WriteLine("data clean is complete.");

            if(missingPDFs.Count > 0)
            {
                using(CsvFileWriter writer = new CsvFileWriter(localFolderPath + "errors.csv"))
                {
                    CsvRow header = new CsvRow();
                    header.AddRange(InvoiceRecord.CsvHeaders());
                    writer.WriteRow(header);
                    foreach (InvoiceRecord record in missingPDFs)
                    {
                        CsvRow current = new CsvRow();
                        current.AddRange(record.ToCsvList());
                        writer.WriteRow(current);
                    }
                }
                Console.WriteLine("missing metadata is saved.");
            }else
            {
                Console.WriteLine("No missing pdf documents in this folder.");
            }
            Console.ReadLine();
        }
    }
    [DelimitedRecord(",")]
    [IgnoreFirst]
    public class InvoiceRecord
    {
        public string InvoiceGUID;
        public string DocumentNumber;
        public string PDFCreated;
        public string InvoiceTypeCode;
        public string CustomerNo;
        public string InvoiceDate;
        public string InvoiceTotal;
        public string CustomerName;
        public string BranchCode;
        public string BranchName;
        public string AuctionName;
        public string GoodGUID;
        public string AuctionID;
        public string InvoiceNumberSuffix;
        public string GoodNo;
        public string PlateNo;
        public string VIN;
        public string ConsignmentVendorNumber;
        public string ConsignmentGoodNumber;

        public static List<string> CsvHeaders()
        {
            return new List<string> { "InvoiceGUID", 
                                        "DocumentNumber", 
                                        "PDFCreated", 
                                        "InvoiceTypeCode", 
                                        "CustomerNo", 
                                        "InvoiceDate", 
                                        "InvoiceTotal", 
                                        "CustomerName", 
                                        "BranchCode",
                                        "BranchName",
                                        "AuctionName",
                                        "GoodGUID",
                                        "AuctionID",
                                        "InvoiceNumberSuffix",
                                        "GoodNo",
                                        "PlateNo",
                                        "VIN",
                                        "ConsignmentVendorNumber",
                                        "ConsignmentGoodNumber"};
        }
        public List<string> ToCsvList()
        {
            return new List<string> { InvoiceGUID, 
                                        DocumentNumber, 
                                        PDFCreated, 
                                        InvoiceTypeCode, 
                                        CustomerNo, 
                                        InvoiceDate, 
                                        InvoiceTotal, 
                                        CustomerName, 
                                        BranchCode, 
                                        BranchName, 
                                        AuctionName, 
                                        GoodGUID, 
                                        AuctionID, 
                                        InvoiceNumberSuffix, 
                                        GoodNo, 
                                        PlateNo, 
                                        VIN, 
                                        ConsignmentVendorNumber, 
                                        ConsignmentGoodNumber };
        }
    }
    public class CsvFileWriter : StreamWriter
    {
        public CsvFileWriter(Stream stream)
            : base(stream)
        {
        }

        public CsvFileWriter(string filename)
            : base(filename)
        {
        }

        /// <summary>
        /// Writes a single row to a CSV file.
        /// </summary>
        /// <param name="row">The row to be written</param>
        public void WriteRow(CsvRow row)
        {
            StringBuilder builder = new StringBuilder();
            bool firstColumn = true;
            foreach (string value in row)
            {
                // Add separator if this isn't the first value
                if (!firstColumn)
                    builder.Append(',');
                //handle empty element which of ""
                string item = value.Trim('"');

                if(value.Trim('"').Length == 0)
                {
                    builder.Append("\"\"");
                }
                // Implement special handling for values that contain comma or quote
                // Enclose in quotes and double up any double quotes
                else if (item.IndexOfAny(new char[] { '"', ',' }) != -1)
                    builder.AppendFormat("\"{0}\"", item.Replace("\"", "\"\""));
                else
                    builder.Append(item);
                firstColumn = false;
            }
            row.LineText = builder.ToString();
            WriteLine(row.LineText);
        }
    }
    public class CsvRow : List<string>
    {
        public string LineText { get; set; }
    }

}
